def startTestingServer():
    from littlesite.custom_reactor import install
    install()

    import random
    from twisted.internet.defer import inlineCallbacks, returnValue
    from twisted.python.failure import Failure
    from twisted.web.client import getPage
    from twisted.web.resource import Resource
    from twisted.web.server import Site, NOT_DONE_YET
    from twisted.internet import reactor
    from twisted.internet.task import deferLater
    from twisted.python import context


    class TestResource(Resource):
        isLeaf = True

        @inlineCallbacks
        def handle(self, method, request):
            try:
                result = yield method(request)
                request.write(str(result))
                request.finish()
            except:
                request.processingFailed(Failure())

        def render_GET(self, request):
            ctx = {'request': request}
            context.call(ctx, self.handle, self.doGet, request)
            return NOT_DONE_YET

        @inlineCallbacks
        def doGet(self, request):
            if 'shutdown' in request.args:
                reactor.callLater(1, reactor.stop)
            if 'num' in request.args:
                yield getPage('http://localhost:8080')
                yield getPage('http://localhost:8080')
                yield getPage('http://localhost:8080')
                yield getPage('http://localhost:8080')
            result = yield deferLater(reactor, random.random(), self.returnResult)
            returnValue(result)

        def returnResult(self):
            request = context.get('request')
            if request:
                return request.args.get('num', 0)
            else:
                return 'oooops'

    test_res = TestResource()
    reactor.listenTCP(8080, Site(test_res))
    reactor.run()


def runTest():
    import urllib2
    import hashlib
    from threading import Thread
    from twisted.internet import defer

    class Checker(Thread):
        def __init__(self, num):
            self.n = num
            self.num = hashlib.md5(str(num)).hexdigest()
            self.d = defer.Deferred()
            Thread.__init__(self)

        def run(self):
            ret = {'ok': 0, 'error': 0, 'fail': 0}
            for i in range(5):
                try:
                    f = urllib2.urlopen('http://localhost:8080/test?num=%s' % self.num)
                    if self.num in f.read():
                        print '%s\tok' % self.n
                        ret['ok'] += 1
                    else:
                        print '%s\tfailed' % self.n
                        ret['fail'] += 1
                except:
                    print '%s\terror' % self.n
                    ret['error'] += 1
            self.d.callback(ret)

    def stopTestingServer():
        urllib2.urlopen('http://localhost:8080/test?shutdown=1')

    def stats(result):
        ok = 0
        error = 0
        fail = 0
        for success, r in result:
            ok += r['ok']
            error += r['error']
            fail += r['fail']
        print 'Passed: %(ok)s, failed: %(fail)s, error: %(error)s' % locals()

    deferreds = []
    for i in range(300):
        c = Checker(i)
        deferreds.append(c.d)
        c.start()
    final = defer.DeferredList(deferreds)
    final.addCallback(stats)
    final.addBoth(lambda *x: stopTestingServer())


if __name__ == '__main__':
    import os
    import sys
    sys.path.append('.')
    pid = os.fork()
    if pid:
        startTestingServer()
    else:
        import time
        time.sleep(5)
        runTest()
